package modeles;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;


public class TripleDES {
	String key1;
	String key2;
	String key3;
	String message;
	String tot_string ="";
	DES_Encrypt des = new DES_Encrypt(key1, message);
	CBC cbc;
	ECB ecb;
	CFB cfb;
	OFB ofb;
	
	public String retour_decrypt = "";


	public TripleDES(String key1, String key2, String key3, String message) {
		super();
		this.key1 = key1;
		this.key2 = key2;
		this.key3 = key3;
		this.message = message;
		cbc = new CBC(des);
		ecb = new ECB(des);
		cfb = new CFB(des);
		ofb = new OFB(des);
	}


	/**
	 * Chiffre un message en utilisant l'algorithme de triple DES.
	 * @return le résultat de l'encryption.
	 */
	public int[] doEncryption(String mode) {
		System.out.println("message : "+message);
		System.out.println("key1 : "+key1);
		System.out.println("key2 : "+key2);
		System.out.println("key3 : "+key3);

		int[] key1_bit = des.doStringtoBin(key1);
		int[] key2_bit = des.doStringtoBin(key2);
		int[] key3_bit = des.doStringtoBin(key3);


		int[] message_bit = des.doStringtoBin(message);
		int[] res = null;
		if (mode.equals("ECB")){
			res = ecb.encrypt(key1_bit, message_bit, true);
			res = ecb.encrypt(key2_bit, res, false);
			res = ecb.encrypt(key3_bit, res, true);
		}
		else if (mode.equals("CBC")){
			res = cbc.encrypt(key1_bit, message_bit);
			res = cbc.decrypt(key2_bit, res);
			res = cbc.encrypt(key3_bit, res);

		}
		else if (mode.equals("CFB")){
			res = cfb.encrypt(key1_bit, message_bit);
			res = cfb.decrypt(key2_bit, res);
			res = cfb.encrypt(key3_bit, res);
		}
		else if (mode.equals("OFB")){
			res = ofb.encrypt(key1_bit, message_bit);
			res = ofb.decrypt(key2_bit, res);
			res = ofb.encrypt(key3_bit, res);
		}

		return res;

	}


	/**
	 * Méthode qui réalise le dechiffrement d'un message encodé avec
	 * triple DES.
	 * @param message : message à decrypter.
	 * @return message decrypté.
	 */
	public int[] doDecryption(String message, String mode) {
		System.out.println("message : "+message);
		System.out.println("key1 : "+key1);
		System.out.println("key2 : "+key2);
		System.out.println("key3 : "+key3);

		int[] key1_bit = des.doStringtoBin(key1);
		int[] key2_bit = des.doStringtoBin(key2);
		int[] key3_bit = des.doStringtoBin(key3);


		int[] message_bit = des.doStringtoBin(message);
		int[] res = null;
		if (mode.equals("ECB")){
			res = ecb.encrypt(key3_bit, message_bit, false);
			res = ecb.encrypt(key2_bit, res, true);
			res = ecb.encrypt(key1_bit, res, false);
		}
		else if (mode.equals("CBC")){
			res = cbc.decrypt(key3_bit, message_bit);
			res = cbc.encrypt(key2_bit, res);
			res = cbc.decrypt(key1_bit, res);

		}
		else if (mode.equals("CFB")){
			res = cfb.decrypt(key3_bit, message_bit);
			res = cfb.encrypt(key2_bit, res);
			res = cfb.decrypt(key1_bit, res);
		}
		else if (mode.equals("OFB")){
			res = ofb.decrypt(key3_bit, message_bit);
			res = ofb.encrypt(key2_bit, res);
			res = ofb.decrypt(key1_bit, res);
		}

		return res;

	}

	public int[] doDecryption(int[] message_bit, String mode){
		System.out.println("message : "+message);
		System.out.println("key1 : "+key1);
		System.out.println("key2 : "+key2);
		System.out.println("key3 : "+key3);

		int[] key1_bit = des.doStringtoBin(key1);
		int[] key2_bit = des.doStringtoBin(key2);
		int[] key3_bit = des.doStringtoBin(key3);


		int[] res = null;

		if (mode.equals("ECB")){
			res = ecb.encrypt(key3_bit, message_bit, false);
			res = ecb.encrypt(key2_bit, res, true);
			res = ecb.encrypt(key1_bit, res, false);
		}
		else if (mode.equals("CBC")){
			res = cbc.decrypt(key3_bit, message_bit);
			res = cbc.encrypt(key2_bit, res);
			res = cbc.decrypt(key1_bit, res);

		}
		else if (mode.equals("CFB")){
			res = cfb.decrypt(key3_bit, message_bit);
			res = cfb.encrypt(key2_bit, res);
			res = cfb.decrypt(key1_bit, res);
		}
		else if (mode.equals("OFB")){
			res = ofb.decrypt(key3_bit, message_bit);
			res = ofb.encrypt(key2_bit, res);
			res = ofb.decrypt(key1_bit, res);
		}

		return res;

	}

	public void doBintoString(int[] tab){
		tot_string = "";
		String bin_ligne = "";
		int deb_ligne = 0;
		int char_int;
		char test;
		char[] fin = new char[tab.length/8]; //au plus, 1 char = 1 ligne donc taille/8
		boolean ptr_fin = false;
		int nb_lignes = 1; //nbres de lignes (=octet) sur lequel est codé le char

		for (int i=0; deb_ligne<tab.length; i++){ //au plus, 1 char = 1 ligne donc taille/8
			bin_ligne="";
			System.out.println("debut ligne : "+deb_ligne);
			//choix nb lignes
			if (tab[deb_ligne]== 1 && tab[deb_ligne+1]==1){ //char codés sur + de 8 bits
				nb_lignes = 2;
				if (tab[deb_ligne+2]==1){
					nb_lignes = 3;
					if (tab[deb_ligne+3]==1)
						nb_lignes = 4;
				}
			}

			if(nb_lignes == 1) {
				for (int j=deb_ligne; j<deb_ligne+8; j++){	
					bin_ligne += String.valueOf(tab[j]); 
				}
				deb_ligne+=8;
			}
			else if (nb_lignes == 2){
				for (int j=deb_ligne; j<deb_ligne+(8*2); j++){	//2 lignes
					bin_ligne += String.valueOf(tab[j]); 
				}
				deb_ligne+=(8*2);
			}
			else if (nb_lignes == 3){
				for (int j=deb_ligne; j<deb_ligne+(8*3); j++){	//2 lignes
					bin_ligne += String.valueOf(tab[j]); 
				}
				deb_ligne+=(8*3);	
			}
			else if (nb_lignes == 4){
				for (int j=deb_ligne; j<deb_ligne+(8*4); j++){	//2 lignes
					bin_ligne += String.valueOf(tab[j]); 
				}
				deb_ligne+=(8*4);	
			}


			char_int = Integer.parseInt(bin_ligne, 2);
			test = (char) char_int;
			fin[i] = test;
			nb_lignes = 1;
			System.out.println("char : "+test);

		}

		for (int i =0; i<fin.length; i++){
			System.out.println(fin[i]);
		}
		String coucou = new String(fin);
		System.out.println("coucou ; " +coucou);
		tot_string = coucou;


	}

	public void binToString(int[][] total, int nbBlocs){
		tot_string = "";
		String[] total_bloc; //8 lignes de bin en string = 1 bloc
		int bloc, i_ligne=0, i_colonne=0;
		String file = "./result.txt";
		try{
			FileOutputStream fos = new FileOutputStream(file);

			//pour chaque bloc
			for (bloc=0; bloc<nbBlocs; bloc++){
				//pour un bloc
				total_bloc = new String[8]; //8 lignes par bloc
				for (i_ligne=0; i_ligne<8; i_ligne++){
					//pour une ligne
					total_bloc[i_ligne] = "";
					for (i_colonne=0; i_colonne<8; i_colonne++){
						//pour un bin
						total_bloc[i_ligne]+=String.valueOf(total[bloc][i_colonne+(i_ligne*8)]);
					}
					int char_int = Integer.parseInt(total_bloc[i_ligne], 2);
					//System.out.println("char en int : "+char_int);
					fos.write((byte)char_int);  
					String coucou = new String(new byte[8]);
					tot_string+=(char)char_int;

				}
			}
			fos.close();
		}
		catch(IOException e){
			System.err.println("erreur fichier : "+e);	
		}

	}


}
